home *** CD-ROM | disk | FTP | other *** search
- #include "yakems.h"
- #include "mem.h"
- #include "iostream.h"
-
- word emsBlock::wPageFrame = NULL;
- pyList emsBlock::LBlockList;
- int emsBlock::iCurrentHandle = 0;
-
- void emsData::deAllocate()
- {
- //#ifndef NDEBUG
- // cerr << "\nNow Deallocating " << this << ": pbDataPtr = " << pbDataPtr << ", handle = " << iHandle << ", size = " << wSize;
- //#endif
- if (iHandle)
- {
- ptListIterator<emsBlock> tIBlockIterator(emsBlock::LBlockList);
- while ((int)tIBlockIterator && (iHandle != tIBlockIterator.ptCurrent()->iHandle))
- ++tIBlockIterator; //find the block we're in
- if ((int)tIBlockIterator)
- {
- ptListIterator<emsData> tIDataIterator(tIBlockIterator.ptCurrent()->LDataList);
- while ((int)tIDataIterator && (this != tIDataIterator.ptCurrent()))
- ++tIDataIterator;
- if ((int)tIDataIterator && (int)tIBlockIterator)
- {
- tIDataIterator.pnThisNode->pnPrev->pnNext = tIDataIterator.pnThisNode->pnNext;
- tIDataIterator.pnThisNode->pnNext->pnPrev = tIDataIterator.pnThisNode->pnPrev;
- }
- }
- }
- // else if (pbDataPtr)
- // delete pbDataPtr;
- pbDataPtr = NULL;
- iHandle = 0;
- wSize = 0;
- }
- emsData::emsData()
- {
- //#ifndef NDEBUG
- // cerr << "\nCreating new emsData block " << this;
- //#endif
- pbDataPtr = NULL;
- iHandle = 0;
- wSize = 0;
- };
-
- emsData::~emsData() //this is a pain; it must be removed from the list first.
- {
- //#ifndef NDEBUG
- // cerr << "\nNow Destroying " << this;
- //#endif
- deAllocate();
- }
-
- byte * emsData::pbUseData(void * dataToUse, word wSizeMoved)
- {
- pbData();
- if (pbDataPtr && (wSizeMoved <= wSize))
- {
- memcpy(pbDataPtr, dataToUse, wSize);
- return pbDataPtr;
- }
- else
- return NULL;
- }
-
- byte * emsData::pbAllocate(word wSizeToAllocate)
- {
- //#ifndef NDEBUG
- // cerr << "\nNow Allocating " << wSizeToAllocate << " bytes for " << this;
- //#endif
- if (pbDataPtr)
- deAllocate();
- if (wSizeToAllocate == 0)
- {
- wSize = 0;
- pbDataPtr = NULL;
- iHandle = 0;
- return pbDataPtr;
- }
- ASSERT(wSizeToAllocate > 0);
- ptListIterator<emsBlock> tIBlockIterator(emsBlock::LBlockList);
- emsBlock * myBlock = NULL;
- if (emsBlock::wPageFrame)
- {
- while ((int)tIBlockIterator)
- {
- ptListIterator<emsData> tIDataIterator(tIBlockIterator.ptCurrent()->LDataList);
- word startLoc = 0, endLoc = 0;
- while((int)tIDataIterator)
- {
- startLoc = (FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr) + tIDataIterator.ptCurrent()->wSize); //the location of this block
- if (tIDataIterator.pnThisNode->pnNext == &(tIBlockIterator.ptCurrent()->LDataList.nTail))
- endLoc = 65535;
- else
- endLoc = FP_OFF(((emsData *)(tIDataIterator.pnThisNode->pnNext->pyData))->pbDataPtr);
- if ((endLoc - startLoc) >= wSizeToAllocate)
- {
- myBlock = ((emsBlock *)tIBlockIterator.ptCurrent());
- myBlock->LDataList.addNode(new pyListNode(this, tIDataIterator.pnThisNode->pnNext));
- iHandle = myBlock->iHandle;
- pbDataPtr = (byte *)MK_FP(emsBlock::wPageFrame, startLoc);
- wSize = wSizeToAllocate;
- if (iHandle)
- return pbDataPtr;
- }
- ++tIDataIterator;
- }
- ++tIBlockIterator;
- }
- if (!myBlock)
- {
- myBlock = new emsBlock;
- myBlock->bIsTemporary = 1;
- emsBlock::LBlockList.addTail(myBlock);
- }
- if (myBlock && (myBlock->iHandle)) //it's a new block, in other words
- {
- iHandle = myBlock->iHandle;
- pbDataPtr = (byte *)MK_FP(emsBlock::wPageFrame, 0);
- wSize = wSizeToAllocate;
- myBlock->LDataList.addTail(this);
- }
- else
- emsBlock::LBlockList.removeTail();
- }
- if (!pbDataPtr)
- {
- iHandle = 0;
- pbDataPtr = new byte[wSize = wSizeToAllocate];
- }
- if (iHandle)
- ASSERT(((long)FP_OFF(pbDataPtr) + (long)wSize) < (long)65535);
- return pbDataPtr;
- }
-
- byte * emsData::pbData(void)
- {
- if (iHandle)
- // if (iHandle && (iHandle!=emsBlock::iCurrentHandle))
- {
- wEms_map(0, iHandle, 0);
- wEms_map(1, iHandle, 1);
- wEms_map(2, iHandle, 2);
- wEms_map(3, iHandle, 3);
- emsBlock::iCurrentHandle = iHandle;
- }
- if (iHandle)
- ASSERT(FP_SEG(pbDataPtr) == emsBlock::wPageFrame);
- return pbDataPtr;
- };
-
- word emsBlock::wInit(void)
- {
- if (wEms_verify())
- {
- wPageFrame = wEms_getframe();
- return 1;
- }
- else
- {
- wPageFrame = 0;
- return 0;
- }
- };
-
- emsBlock::emsBlock(void)
- {
- iHandle = wEms_alloc(4);
- }
-
- //frees a handle
- emsBlock::~emsBlock(void)
- {
- LDataList.pyList::~pyList();
- if (iHandle)
- wEms_free(iHandle);
- }
-
-
- //emsBlock::swapIn swaps in all four pages of an emsBlock in turn and
- //resets the current handle.
- void emsBlock::swapIn(void)
- {
- wEms_map(0, iHandle, 0);
- wEms_map(1, iHandle, 1);
- wEms_map(2, iHandle, 2);
- wEms_map(3, iHandle, 3);
- iCurrentHandle = iHandle;
- }
-
- //emsBlock::defragment steps through every emsData entry in an emsBlock
- //and moves it up in the block until all free spaces are filled.
- //pointers in the emsData blocks are updated to include the new information.
-
- void emsBlock::defragment(void)
- {
- swapIn();
- word wLastData = 0;
- ptListIterator<emsData> tIDataIterator(LDataList);
- while((int)tIDataIterator)
- {
- if (wLastData < FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr))
- {
- memmove(MK_FP(wPageFrame, wLastData),
- MK_FP(wPageFrame, FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr)),
- tIDataIterator.ptCurrent()->wSize);
- tIDataIterator.ptCurrent()->pbDataPtr = (byte *)MK_FP(wPageFrame, wLastData);
-
- }
- wLastData += tIDataIterator.ptCurrent()->wSize;
- ++tIDataIterator;
- }
- }
-
- //emsBlock::defragmentAllEMS steps through every block of EMS allocated
- //and defragments it in turn.
-
- void emsBlock::defragmentAllEMS(void)
- {
- ptListIterator<emsBlock> tIBlockIterator(LBlockList);
- while((int)tIBlockIterator)
- {
- tIBlockIterator.ptCurrent()->defragment();
- ++tIBlockIterator;
- }
- }
-
-
- void emsBlock::showBlockStatus()
- {
- ptListIterator<emsBlock> tIBlockIterator(emsBlock::LBlockList);
- while((int)tIBlockIterator)
- {
- cout << "\nNew Block: Handle = " << tIBlockIterator.ptCurrent()->iHandle << ":\n";
- ptListIterator<emsData> tIDataIterator(tIBlockIterator.ptCurrent()->LDataList);
- while((int)tIDataIterator)
- {
- cout << " Data block-- start: " << FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr);
- cout << "\t end: " << FP_OFF(tIDataIterator.ptCurrent()->pbDataPtr) + tIDataIterator.ptCurrent()->wSize - 1;
- cout << "\t size: " << tIDataIterator.ptCurrent()->wSize << "\n";
- ++tIDataIterator;
- }
- ++tIBlockIterator;
- }
- }
-
- void emsBlock::freeAllEMS()
- {
- while (!LBlockList.iIsEmpty())
- LBlockList.removeTail();
- }